//
//  TTSEngine.swift
//  SitPosition
//
//  Created by apple on 2018/12/23.
//  Copyright © 2018 apple. All rights reserved.
//

import Foundation
import AVFoundation


/**
 * 朗读文本类型（纯文本、富文本）
 */
public enum TTSSpeechUtterance {
    case none
    case plainText(String)
    case attributedText(NSAttributedString)
    
    static func ==(lhs: TTSSpeechUtterance, rhs: TTSSpeechUtterance) -> Bool {
        switch (lhs, rhs) {
        case (.none, .none): return true
        case (.plainText(let s1), .plainText(let s2)):
            return s1 == s2
        case (.attributedText(let as1), .attributedText(let as2)):
            return as1 == as2
        default:
            return false
        }
    }
    
    static func !=(lhs: TTSSpeechUtterance, rhs: TTSSpeechUtterance) -> Bool {
        return !(lhs == rhs)
    }
}

public protocol TTSEngineDelegate : NSObjectProtocol {
    
    func ttsEngineDidStart(_ engine: TTSEngine)
    
    func ttsEngineDidFinish(_ engine: TTSEngine)
    
    func ttsEngineDidPause(_ engine: TTSEngine)
    
    func ttsEngineDidContinue(_ engine: TTSEngine)
    
    func ttsEngineDidCancel(_ engine: TTSEngine)
    
    func ttsEngine(_ engine: TTSEngine, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: TTSSpeechUtterance)
}


@objc public class TTSEngine : NSObject {
    
    // 代理对象
    public weak var delegate: TTSEngineDelegate? = nil
    
    // 声音
    private lazy var voice: AVSpeechSynthesisVoice? = {
        let voice = AVSpeechSynthesisVoice(language: "zh-CN")
        return voice
    }()
    
    // 人（协调器）
    private lazy var synthesizer: AVSpeechSynthesizer = {
        let synthesizer = AVSpeechSynthesizer()
        synthesizer.delegate = self
        return synthesizer
    }()
    
    // 获得当前设备支持的声音
    public static func speechVoices() -> [AVSpeechSynthesisVoice] {
        return AVSpeechSynthesisVoice.speechVoices()
    }
    
    // 朗读指定文本
    private var _utterance: TTSSpeechUtterance = TTSSpeechUtterance.none
    public func speak(_ speechUtterance: TTSSpeechUtterance) {
        guard speechUtterance != TTSSpeechUtterance.none else {
            return
        }
        stopSpeaking()
        _utterance = speechUtterance
        
        var utterance: AVSpeechUtterance
        switch speechUtterance {
        case .plainText(let text):
            utterance = AVSpeechUtterance(string: text)
        case .attributedText(let attribsString):
            utterance = AVSpeechUtterance(attributedString: attribsString)
        default:
            fatalError()
        }
        utterance.pitchMultiplier = 0.8
        utterance.preUtteranceDelay = 0.25
        utterance.rate = AVSpeechUtteranceDefaultSpeechRate
        utterance.voice = voice
        utterance.volume = 1
        
        synthesizer.speak(utterance)
    }
    
    // 停止朗读
    public func stopSpeaking() {
        guard isSpeaking() || isPaused() else { return }
        synthesizer.stopSpeaking(at: AVSpeechBoundary.word)
    }
    
    // 暂停朗读
    public func pauseSpeaking() {
        guard isSpeaking() else { return }
        synthesizer.pauseSpeaking(at: AVSpeechBoundary.word)
    }
    
    // 恢复朗读
    public func resumeSpeaking() {
        guard isPaused() else { return }
        synthesizer.continueSpeaking()
    }
    
    // 判断是否是朗读状态？
    public func isSpeaking() -> Bool {
        return synthesizer.isSpeaking
    }
    
    // 判断是否是暂停状态？
    public func isPaused() -> Bool {
        return synthesizer.isPaused
    }
}


extension TTSEngine : AVSpeechSynthesizerDelegate {
    
    public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didStart utterance: AVSpeechUtterance) {
        delegate?.ttsEngineDidStart(self)
    }
    
    public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
        delegate?.ttsEngineDidFinish(self)
    }
    
    public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didPause utterance: AVSpeechUtterance) {
        delegate?.ttsEngineDidPause(self)
    }
    
    public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didContinue utterance: AVSpeechUtterance) {
        delegate?.ttsEngineDidContinue(self)
    }
    
    public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) {
        delegate?.ttsEngineDidCancel(self)
    }
    
    public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance) {
        delegate?.ttsEngine(self, willSpeakRangeOfSpeechString: characterRange, utterance: _utterance)
    }
}
